package com.itheima.file.service.impl;

import com.itheima.file.service.FileService;
import com.itheima.file.service.FileStorageService;
import com.itheima.model.common.dtos.ResponseResult;
import com.itheima.model.common.enums.AppHttpCodeEnum;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;

import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.UUID;

@Service
@Slf4j
public class FileServiceImpl implements FileService {

    @Autowired
    private FileStorageService fileStorageService;

    // 文件大小限制：10MB
    private static final long MAX_FILE_SIZE = 10 * 1024 * 1024;
    // 批量上传数量限制
    private static final int MAX_BATCH_SIZE = 10;

    /**
     * 上传单文件
     *
     * @param file 上传的文件
     * @return ResponseResult
     */
    @Override
    public ResponseResult uploadFile(MultipartFile file) {
        log.info("接收到文件上传请求，文件名: {}, 大小: {} bytes",
                file.getOriginalFilename(), file.getSize());

        try {
            // 验证文件
            if (!validateFile(file)) {
                return ResponseResult.errorResult(AppHttpCodeEnum.PARAM_INVALID, "文件验证失败");
            }

            // 上传文件到 MinIO
            String fileUrl = uploadToStorage(file);

            log.info("文件上传成功，URL: {}", fileUrl);
            return ResponseResult.okResult(fileUrl);

        } catch (Exception e) {
            log.error("文件上传失败", e);
            return ResponseResult.errorResult(AppHttpCodeEnum.SERVER_ERROR,
                    "文件上传失败: " + e.getMessage());
        }
    }

    /**
     * 批量文件上传
     *
     * @param files 上传的文件数组
     * @return ResponseResult
     */
    @Override
    public ResponseResult uploadFiles(MultipartFile[] files) {
        log.info("接收到批量文件上传请求，文件数量: {}", files.length);

        try {
            // 验证文件数量
            if (files == null || files.length == 0) {
                return ResponseResult.errorResult(AppHttpCodeEnum.PARAM_INVALID,
                        "请选择要上传的文件");
            }

            if (files.length > MAX_BATCH_SIZE) {
                return ResponseResult.errorResult(AppHttpCodeEnum.PARAM_INVALID,
                        "单次最多上传" + MAX_BATCH_SIZE + "个文件");
            }

            List<String> fileUrls = new ArrayList<>();

            for (MultipartFile file : files) {
                // 跳过空文件
                if (file.isEmpty()) {
                    log.warn("跳过空文件");
                    continue;
                }

                // 验证单个文件
                if (!validateFile(file)) {
                    return ResponseResult.errorResult(AppHttpCodeEnum.PARAM_INVALID,
                            "文件 " + file.getOriginalFilename() + " 验证失败");
                }

                // 上传文件
                String fileUrl = uploadToStorage(file);
                fileUrls.add(fileUrl);
            }

            log.info("批量文件上传成功，数量: {}", fileUrls.size());
            return ResponseResult.okResult(fileUrls);

        } catch (Exception e) {
            log.error("批量文件上传失败", e);
            return ResponseResult.errorResult(AppHttpCodeEnum.SERVER_ERROR,
                    "批量文件上传失败: " + e.getMessage());
        }
    }

    /**
     * 删除文件
     *
     * @param fileUrl 文件URL
     * @return ResponseResult
     */
    @Override
    public ResponseResult deleteFile(String fileUrl) {
        log.info("接收到文件删除请求，URL: {}", fileUrl);

        try {
            if (fileUrl == null || fileUrl.trim().isEmpty()) {
                return ResponseResult.errorResult(AppHttpCodeEnum.PARAM_INVALID,
                        "文件URL不能为空");
            }

            fileStorageService.delete(fileUrl);
            log.info("文件删除成功");
            return ResponseResult.okResult(AppHttpCodeEnum.SUCCESS);

        } catch (Exception e) {
            log.error("文件删除失败", e);
            return ResponseResult.errorResult(AppHttpCodeEnum.SERVER_ERROR,
                    "文件删除失败: " + e.getMessage());
        }
    }

    /**
     * 验证文件
     *
     * @param file 待验证的文件
     * @return true-验证通过，false-验证失败
     */
    private boolean validateFile(MultipartFile file) {
        // 验证文件是否为空
        if (file.isEmpty()) {
            log.error("文件不能为空");
            return false;
        }

        // 验证文件大小
        if (file.getSize() > MAX_FILE_SIZE) {
            log.error("文件大小超过限制: {} bytes", file.getSize());
            return false;
        }

        // 验证文件类型（只允许图片）
        String contentType = file.getContentType();
        if (contentType == null || !contentType.startsWith("image/")) {
            log.error("不支持的文件类型: {}", contentType);
            return false;
        }

        // 验证文件名
        String originalFilename = file.getOriginalFilename();
        if (originalFilename == null || !originalFilename.contains(".")) {
            log.error("文件名格式不正确: {}", originalFilename);
            return false;
        }

        return true;
    }

    /**
     * 上传文件到存储服务
     *
     * @param file 待上传的文件
     * @return 文件访问URL
     * @throws IOException IO异常
     */
    private String uploadToStorage(MultipartFile file) throws IOException {
        // 生成唯一文件名
        String fileName = UUID.randomUUID().toString().replace("-", "");
        String originalFilename = file.getOriginalFilename();
        String suffix = originalFilename.substring(originalFilename.lastIndexOf("."));

        // 上传到 MinIO
        String fileUrl = fileStorageService.uploadImgFile("",
                fileName + suffix,
                file.getInputStream());

        log.info("上传图片到 MinIO 成功，文件地址：{}", fileUrl);
        return fileUrl;
    }
}